/*
 * @Author: _oufen
 * @Date: 2023-07-11 20:23:19
 * @LastEditTime: 2023-07-19 15:26:17
 * @Description:  这是一个模板文件
 */
/**
 *************************************************************************************************************************
 * @file    encoder.c
 * @author  oufen
 * @version V1.0
 * @date    2023-07-17
 * @brief   外部中断读取编码器
 *************************************************************************************************************************
 * @attention
 * 注意这里没有使用TIM4123G 自带的编码器    而是使用外部中断获取编码器的数据
 * 所以  不是像32一样的4倍频        而是二倍频
 * 左电机   A相     PD1     B相     PD0
 * 右电机   A相     PD3     B相     PD2
 *************************************************************************************************************************
 */

/* Includes -------------------------------------------------------------------------------------------------------------*/
#include "encoder.h"
/* 定义 -----------------------------------------------------------------------------------------------------------------*/

Encoder_Typedef Encoder; // 电机参数结构体

/**
 * @brief   获取编码器的读数
 * @param 	Choose  1-> 左电机的脉冲    2->右电机的脉冲
 * @retval  无
 */
int32_t Encoder_Get(uint8_t Choose)
{
    int32_t temp;
    if (Choose == 1)
    {
        temp = Encoder.Left_Cnt;
        Encoder.Left_Cnt = 0; // 读取后清零
    }
    else if (Choose == 2)
    {
        temp = Encoder.Right_Cnt;
        Encoder.Right_Cnt = 0; // 读取后清零
    }

    return temp;
}

/**
 * @brief   外部中断服务函数
 * @param 	无
 * @retval  无
 */
void PortDIntHandler(void) // 外部中断D服务函数     二倍频计数
{
    uint32_t flag = GPIOIntStatus(GPIO_PORTD_BASE, true); // 读取中断状态

    // 左电机的  A相  PD0  B相   PD1

    // 左轮编码器A相    PD0
    if ((flag & GPIO_PIN_0) == GPIO_PIN_0) // 判断是否为GPIOD_PIN_0引起的中断
    {
        GPIOIntClear(GPIO_PORTD_BASE, GPIO_PIN_0); // 清除中断标志PD0

        if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_1) == 0) // PD0 高电平  PD1 低电平  正转      //forward
        {
            Encoder.Left_Motor_Dir = 1; // 正转
            Encoder.Left_Cnt++;         // 脉冲数++
        }
        // else if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_1) == 1) // PD0 高电平  PD1 高电平   反转  不知道为啥这里会检测不到 所以直接else
        // 现在知道了  GPIOPinRead      -->     返回的是    GPIO_PIN_X 或   0
        else // back
        {
            Encoder.Left_Motor_Dir = -1; // 反转
            Encoder.Left_Cnt--;          // 脉冲数--
        }
    }

    // 左轮编码器B相    PD1
    if ((flag & GPIO_PIN_1) == GPIO_PIN_1)
    {
        GPIOIntClear(GPIO_PORTD_BASE, GPIO_PIN_1);         // 清除中断标志PD1
        if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_0) == 1) // PD1 高电平  PD0  高电平   正转        forward
        {
            Encoder.Left_Motor_Dir = 1; // 正转
            Encoder.Left_Cnt++;         // 脉冲数++
        }
        else if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_0) == 0) // PD1 高电平  PD0 低电平  反转     back
        {
            Encoder.Left_Motor_Dir = -1; // 反转
            Encoder.Left_Cnt--;          // 脉冲数--
        }
    }

    // 右电机编码器 A相 PD2     B相 PD3

    // 右电机A相 PD2
    if ((flag & GPIO_PIN_2) == GPIO_PIN_2)
    {
        GPIOIntClear(GPIO_PORTD_BASE, GPIO_PIN_2);         // 清除中断标志PD2
        if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_3) == 0) // PD2 高电平  PD3 低电平  正转   forward
        {
            Encoder.Right_Motor_Dir = 1; // 正转
            Encoder.Right_Cnt++;         // 脉冲数++
        }

        // else if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_3) == 1) // PD2 高电平  PD3 高电平  反转  back
        else
        {
            Encoder.Right_Motor_Dir = -1; // 反转
            Encoder.Right_Cnt--;          // 脉冲数--
        }
    }

    if ((flag & GPIO_PIN_3) == GPIO_PIN_3)
    {
        GPIOIntClear(GPIO_PORTD_BASE, GPIO_PIN_3); // 清除中断标志PD3

        if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_2) == 0) // PD3 高电平  PD2 低电平  反转  back

        {
            Encoder.Right_Motor_Dir = -1; // 反转
            Encoder.Right_Cnt--;          // 脉冲数--
        }
        //  else if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_2) == 1) // PD3 高电平  PD2  高电平   正转   forward
        else
        {
            Encoder.Right_Motor_Dir = 1; // 正转
            Encoder.Right_Cnt++;         // 脉冲数++
        }
    }
}

/**
 * @brief   外部中断读取编码器  对应外部中断引脚初始化      PD1 PD3仅作输入功能     如果这样做的话就是一倍频
 * @param 	无
 * @retval  无
 */
// void Encoder_GPIO_Init()
// {
//     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // 使能    GPIOD   外设

//     ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_1); // 配置输入   PD1    这两个引脚仅作为输入功能
//     ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_3); // 配置输入   PD3    这两个引脚仅作为输入功能
// }

/**
 * @brief   外部中断读取编码器  对应外部中断引脚初始化      PD1 A相 PD0 B相
 * @param 	无
 * @retval  无
 */
void Encoder_Init(void)
{
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);       // 使能    GPIOD   外设
                                                           // 配置引脚为输入模式
    ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_0); // 配置输入   PD0    这两个引脚作为外部中断
    ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_1); // 配置输入   PD1    这两个引脚作为外部中断
    ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_2); // 配置为输入 PD2    这两个引脚作为外部中断
    ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_3); // 配置输入   PD3    这两个引脚作为外部中断

    // 配置引脚为弱下拉
    ROM_GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD); // 弱下拉
    ROM_GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD); // 弱下拉
    ROM_GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD); // 弱下拉
    ROM_GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD); // 弱下拉

    // 配置触发方式
    ROM_GPIOIntTypeSet(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_RISING_EDGE); // 上升沿触发
    ROM_GPIOIntTypeSet(GPIO_PORTD_BASE, GPIO_PIN_1, GPIO_RISING_EDGE); // 上升沿触发
    ROM_GPIOIntTypeSet(GPIO_PORTD_BASE, GPIO_PIN_2, GPIO_RISING_EDGE); // 上升沿触发
    ROM_GPIOIntTypeSet(GPIO_PORTD_BASE, GPIO_PIN_3, GPIO_RISING_EDGE); // 上升沿触发

    // 外部中断触发  使能   PD0    PD2 中断
    GPIOIntEnable(GPIO_PORTD_BASE, GPIO_PIN_0); // 使能中断
    GPIOIntEnable(GPIO_PORTD_BASE, GPIO_PIN_1); // 使能中断
    GPIOIntEnable(GPIO_PORTD_BASE, GPIO_PIN_2); // 使能中断
    GPIOIntEnable(GPIO_PORTD_BASE, GPIO_PIN_3); // 使能中断

    // 注册中断函数
    GPIOIntRegister(GPIO_PORTD_BASE, PortDIntHandler); // 注册中断函数

    // 设置优先级
    // IntPrioritySet(INT_GPIOD, 0x00); // 优先级最高
    // IntPrioritySet(INT_GPIOD, 0x00);

    // 设置优先级
    ROM_IntPrioritySet(INT_GPIOD, USER_INT0); // 优先级最高 为0x00
}
/*****************************************************END OF FILE*********************************************************/
